/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package wiView.graphics.UI;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.graphstream.ui.j2dviewer.J2DGraphRenderer;
import org.graphstream.ui.swingViewer.View;
import org.graphstream.ui.swingViewer.Viewer;
import wiBase.WiException;
import wiBase.WiObject;
import wiEngine.WiEngine;
import wiView.console.WiObjectOutputStream;
import wiView.graphics.GraphObject.*;
import wiView.graphics.UI.UIComponent.*;
import wiView.graphics.Drawer._Drawer;
import wiView.graphics.ScenarioMaker.*;
import wiEngine.WiEngine.OnEngineControlListener;
import wiBase.baseInterface.OnDrawerListener;
import wiBase.baseObject.*;
import java.awt.Toolkit;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import org.graphstream.ui.swingViewer.basicRenderer.SwingBasicGraphRenderer;

/**
 *
 * @author Hoang
 */
public class GraphForm extends javax.swing.JFrame implements IMediaPanelContainer, IViewContainer, OnEngineControlListener {

    WiGraph graph;
    ArrayList<String> choseElements = new ArrayList<>();
    String selectedNodeId;
    String selectedPacketId;
    String selectedElement;
    Viewer viewer;
    View view;
    MediaControlBoardPanel controlPane;
    //WiSimConsole wiMain;
    WiEngine wiEngine;
    WiObjectOutputStream output;
    _Drawer drawer;
    
    Simulation sim;
    FilterFrame filterFrame;
    NodeProperties nodeProperty;
    PacketProperties packetProperty;
    
    boolean isFocused;
    @Override
    public boolean Play() {
        //throw new UnsupportedOperationException("Not supported yet.");
        if (graph.getNodeCount() == 0) {
            System.out.println("Lam gi co node nao ma Mo phong?");
            return false;
        }

        try {
            drawer.Start();
            output.setTraceEvent(output);
            sim.Run();

        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            return false;
        }
        return true;
    }

    @Override
    public boolean Stop() {
        try {
            wiEngine.stop();
            Thread.sleep(100);
            drawer.Stop();
            drawNodes();
            return true;
        } catch (Exception ex) {
            return false;
        }
    }

    @Override
    public boolean Pause() {
        //throw new UnsupportedOperationException("Not supported yet.");
        sim.Pause();
       
        wiEngine.setStartTime(controlPane.getCurrTime() / (long) 1E3);
        return true;
    }

    @Override
    public boolean Forward() {
        //throw new UnsupportedOperationException("Not supported yet.");
        double speed = wiEngine.getSpeed();
        if (speed > 1 / 10) {
            wiEngine.setSpeed(speed - speed * 0.2, TimeUnit.NANOSECONDS);
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean Backward() {
        //throw new UnsupportedOperationException("Not supported yet.");
        double speed = wiEngine.getSpeed();
        if (speed < 1000) {
            wiEngine.setSpeed(speed + speed * 0.2, TimeUnit.NANOSECONDS);
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void UserSetTimePlay(double time) {
        //throw new UnsupportedOperationException("Not supported yet.");
        wiEngine.pause();
        drawer.resetGraph();

        wiEngine.setStartTime((long) time / (long) 1E3);
        controlPane.setCurrTime((long) time);
        wiEngine.run();
    }

    public void Parse() {
        try {
//            wiMain.getEngine().getAdapter().copyData();
//            wiMain.parse();
            //initGraphViewer();
        } catch (Exception ex) {
            System.out.println(ex.getMessage());

        }

    }

    void _Parse() {
        System.out.println("Parsing..");
        try {
            wiEngine.parse();
        } catch (WiException ex) {
            ex.printStackTrace();
            return;
        }
    }
    /*
     * Follow is Child Class
     */
    /*
     * Method
     */

    void OnPlaying() {
    }
//    WiSimConsole cs;
    double speed = 1d;

    void OnSpeedChange(double s) {
        if (s != speed) {
            wiEngine.setSpeed(s, TimeUnit.NANOSECONDS);
            speed = s;
        }
    }

    void StartEngine() {
//        cs = new WiSimConsole(this, null);
//        wiEngine = cs.getEngine();
//        wiEngine.setNative(true);
        wiEngine = WiEngine.getInstance();
        wiEngine.addOnDrawerListener(this.drawer);
        output = new WiObjectOutputStream(jScrollPane1, tp_console);
        //output.setTraceEvent(output);
        wiEngine.setStartTime(-1);
        wiEngine.setEndTime(-1);
        wiEngine.addEngineControlListener(this);
        output.setTraceEvent(output);
    }

    public OnDrawerListener getDrawer() {
        return drawer;
    }

    void InitControlPanel() {
        controlPane = new MediaControlBoardPanel();
        controlPane.setContainer(this);
        controlPane.setPreferredSize(new Dimension(1000, 50));
    }

    void InitMenu() {
        speedButtonGroup.add(j1RadioButtonMenuItem);
        speedButtonGroup.add(j1_100RadioButtonMenuItem);
        speedButtonGroup.add(jRadioButtonMenuItem110);
        speedButtonGroup.add(jRadioButtonMenuItem120);
        speedButtonGroup.add(jRadioButtonMenuItem150);
        ActionListener al = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                JRadioButtonMenuItem jb = (JRadioButtonMenuItem) ae.getSource();
                double speed = 0;
                if (jb == j1RadioButtonMenuItem) {
                    speed = 1d;
                } else if (jb == j1_100RadioButtonMenuItem) {
                    speed = 100d;

                } else if (jb == jRadioButtonMenuItem110) {
                    speed = 10d;
                } else if (jb == jRadioButtonMenuItem120) {
                    speed = 20d;
                } else if (jb == jRadioButtonMenuItem150) {
                    speed = 50d;
                } else {
                    return;
                }
                OnSpeedChange(speed);
                controlPane.setSpeed((float) 1 / (float) speed);
            }
        };
        j1RadioButtonMenuItem.addActionListener(al);
        j1_100RadioButtonMenuItem.addActionListener(al);
        jRadioButtonMenuItem110.addActionListener(al);
        jRadioButtonMenuItem120.addActionListener(al);
        jRadioButtonMenuItem150.addActionListener(al);
    }
//
//    public void setConsole(WiSimConsole ws) {
//        wiMain = ws;
//        wiEngine = wiMain.getEngine();
//    }

    void InitGraph() {
        graph = new WiGraph("g1");
        viewer = new Viewer(graph, Viewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD);
        viewer.disableAutoLayout();
        view = viewer.addView("v", new J2DGraphRenderer(), false);
        setGraphMouseManager();
    }

    void setGraphMouseManager() {
        ViewMouseManager vmm = new ViewMouseManager(graph, viewer, view);
        vmm.setContainer(this);
    }

    void Start() {
        drawer = new _Drawer(graph);
        StartEngine();
        drawer.setEngine(wiEngine);
        sim = new Simulation(wiEngine, this);
        filterFrame = new FilterFrame(sim, this);
    }

    void drawNodes() {
        ArrayList<Integer> nodes = new ArrayList<>();
        for (WiObject n : wiEngine.getListNodes()) {
            Node node = (Node) n;
            nodes.add(node.id);
        }
        DrawNodes(nodes);
    }

    public void DrawNodes(ArrayList<Integer> nodeIds) {
        if (graph.getNodeCount() != 0) {
            graph.clear();
            graph.reset();
            graph.AddAttribute();
            
        }
        view.removeAll();
     //   view.getCamera().resetView();
        
    
        ArrayList<wiBase.baseObject.Node> nodes = new ArrayList<>();
        for (int id : nodeIds) {
            nodes.add(wiEngine.getNode(id));
        }
        drawer.DrawNodes(nodes);
        jCheckBoxMenuNodeLabel.setState(true);
    }

    protected void InitMyComponents() {
        InitMenu();
        InitControlPanel();
        InitGraph();
        Layout();

        Start();

    }
    // <editor-fold defaultstate="collapsed" desc="user-description">

    // </editor-fold>
    void Layout() {
        Container c = getContentPane();
        jPanel2.add(view, BorderLayout.CENTER);
        jPanel2.add(controlPane, BorderLayout.PAGE_END);
    }

    void onFileOpen(String pathFile) {
        if (wiEngine != null) {
            wiEngine.setTraceFile(pathFile);
            _Parse();
        }
//        if(wiEngine != null){
//            wiEngine.setTraceFile(pathFile);
//        }
//        try {
//            _Parse();
//        } catch (Exception ex) {
//            ex.printStackTrace();
//        }
    }

    /**
     * Creates new form GraphForm
     */
    public GraphForm() {
        initComponents();
        InitMyComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content filterFrame this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        speedButtonGroup = new javax.swing.ButtonGroup();
        jPopupMenu1 = new javax.swing.JPopupMenu();
        jMenuItemCopyToClB = new javax.swing.JMenuItem();
        jMenuItemFocusOn = new javax.swing.JMenuItem();
        jMenuItemProperty = new javax.swing.JMenuItem();
        jMenuItemReset = new javax.swing.JMenuItem();
        jSplitPane1 = new javax.swing.JSplitPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        tp_console = new javax.swing.JTextPane();
        jSplitPane2 = new javax.swing.JSplitPane();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu_File = new javax.swing.JMenu();
        jMenuItem_Open = new javax.swing.JMenuItem();
        jMenuItem_Exit = new javax.swing.JMenuItem();
        jMenu1 = new javax.swing.JMenu();
        jMenu2 = new javax.swing.JMenu();
        j1RadioButtonMenuItem = new javax.swing.JRadioButtonMenuItem();
        j1_100RadioButtonMenuItem = new javax.swing.JRadioButtonMenuItem();
        jRadioButtonMenuItem150 = new javax.swing.JRadioButtonMenuItem();
        jRadioButtonMenuItem120 = new javax.swing.JRadioButtonMenuItem();
        jRadioButtonMenuItem110 = new javax.swing.JRadioButtonMenuItem();
        jCheckBoxMenuNodeLabel = new javax.swing.JCheckBoxMenuItem();
        jMenu_Tool = new javax.swing.JMenu();
        jMenuItem_Export = new javax.swing.JMenuItem();
        jMenuItem2 = new javax.swing.JMenuItem();
        jMenuItemOptionalSimulate = new javax.swing.JMenuItem();
        jMenu_About = new javax.swing.JMenu();
        jMenuItem_Author = new javax.swing.JMenuItem();
        jMenuItem_Manual = new javax.swing.JMenuItem();

        jPopupMenu1.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
            public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
            }
            public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
                jPopupMenu1PopupMenuWillBecomeInvisible(evt);
            }
            public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
            }
        });

        jMenuItemCopyToClB.setText("Copy ID(s)");
        jMenuItemCopyToClB.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemCopyToClBActionPerformed(evt);
            }
        });
        jPopupMenu1.add(jMenuItemCopyToClB);

        jMenuItemFocusOn.setText("Focus");
        jMenuItemFocusOn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemFocusOnActionPerformed(evt);
            }
        });
        jPopupMenu1.add(jMenuItemFocusOn);

        jMenuItemProperty.setText("Property");
        jMenuItemProperty.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemPropertyActionPerformed(evt);
            }
        });
        jPopupMenu1.add(jMenuItemProperty);

        jMenuItemReset.setText("Reset Network");
        jMenuItemReset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemResetActionPerformed(evt);
            }
        });
        jPopupMenu1.add(jMenuItemReset);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("WISIM");
        setExtendedState(Frame.MAXIMIZED_BOTH);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        jSplitPane1.setBackground(new java.awt.Color(153, 153, 153));
        jSplitPane1.setBorder(null);
        BasicSplitPaneDivider divider = ((BasicSplitPaneUI)jSplitPane1.getUI()).getDivider();
        divider.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Console", javax.swing.border.TitledBorder.LEFT, javax.swing.border.TitledBorder.BELOW_TOP));

        //divider.add(new JButton("aaa"),BorderLayout.LINE_END);
        jSplitPane1.setDividerLocation(10005);
        jSplitPane1.setDividerSize(15);
        jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        jSplitPane1.setResizeWeight(1.0);
        jSplitPane1.setMinimumSize(new java.awt.Dimension(35, 100));
        jSplitPane1.setName("Console"); // NOI18N
        jSplitPane1.setOneTouchExpandable(true);

        jScrollPane1.setMinimumSize(new java.awt.Dimension(0, 0));
        jScrollPane1.setPreferredSize(new java.awt.Dimension(50, 50));

        tp_console.setBackground(new java.awt.Color(51, 51, 51));
        jScrollPane1.setViewportView(tp_console);

        jSplitPane1.setRightComponent(jScrollPane1);

        jSplitPane2.setDividerSize(15);
        jSplitPane2.setResizeWeight(0.1);
        jSplitPane2.setOneTouchExpandable(true);

        jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(102, 102, 102)));
        jPanel2.setLayout(new java.awt.BorderLayout());
        jSplitPane2.setRightComponent(jPanel2);
        jSplitPane2.setLeftComponent(jScrollPane2);

        jSplitPane1.setLeftComponent(jSplitPane2);

        getContentPane().add(jSplitPane1, java.awt.BorderLayout.CENTER);

        jMenu_File.setText("File");

        jMenuItem_Open.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItem_Open.setIcon(new javax.swing.ImageIcon(getClass().getResource("/image/folder.png"))); // NOI18N
        jMenuItem_Open.setText("Open");
        jMenuItem_Open.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem_OpenActionPerformed(evt);
            }
        });
        jMenu_File.add(jMenuItem_Open);

        jMenuItem_Exit.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F4, java.awt.event.InputEvent.ALT_MASK));
        jMenuItem_Exit.setIcon(new javax.swing.ImageIcon(getClass().getResource("/image/exit.png"))); // NOI18N
        jMenuItem_Exit.setText("Exit");
        jMenuItem_Exit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem_ExitActionPerformed(evt);
            }
        });
        jMenu_File.add(jMenuItem_Exit);

        jMenuBar1.add(jMenu_File);

        jMenu1.setText("View");

        jMenu2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/image/speed.png"))); // NOI18N
        jMenu2.setText("Speed");

        j1RadioButtonMenuItem.setSelected(true);
        j1RadioButtonMenuItem.setText("1");
        jMenu2.add(j1RadioButtonMenuItem);

        j1_100RadioButtonMenuItem.setText("1/100");
        jMenu2.add(j1_100RadioButtonMenuItem);

        jRadioButtonMenuItem150.setSelected(true);
        jRadioButtonMenuItem150.setText("1/50");
        jMenu2.add(jRadioButtonMenuItem150);

        jRadioButtonMenuItem120.setSelected(true);
        jRadioButtonMenuItem120.setText("1/20");
        jMenu2.add(jRadioButtonMenuItem120);

        jRadioButtonMenuItem110.setSelected(true);
        jRadioButtonMenuItem110.setText("1/10");
        jMenu2.add(jRadioButtonMenuItem110);

        jMenu1.add(jMenu2);

        jCheckBoxMenuNodeLabel.setSelected(true);
        jCheckBoxMenuNodeLabel.setText("Node Label");
        jCheckBoxMenuNodeLabel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBoxMenuNodeLabelActionPerformed(evt);
            }
        });
        jMenu1.add(jCheckBoxMenuNodeLabel);

        jMenuBar1.add(jMenu1);

        jMenu_Tool.setText("Tool");

        jMenuItem_Export.setText("Export");
        jMenu_Tool.add(jMenuItem_Export);

        jMenuItem2.setText("Find");
        jMenu_Tool.add(jMenuItem2);

        jMenuItemOptionalSimulate.setText("Filter");
        jMenuItemOptionalSimulate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemOptionalSimulateActionPerformed(evt);
            }
        });
        jMenu_Tool.add(jMenuItemOptionalSimulate);

        jMenuBar1.add(jMenu_Tool);

        jMenu_About.setText("About");

        jMenuItem_Author.setIcon(new javax.swing.ImageIcon(getClass().getResource("/image/author.png"))); // NOI18N
        jMenuItem_Author.setText("Author");
        jMenu_About.add(jMenuItem_Author);

        jMenuItem_Manual.setIcon(new javax.swing.ImageIcon(getClass().getResource("/image/manual.png"))); // NOI18N
        jMenuItem_Manual.setText("Manual");
        jMenu_About.add(jMenuItem_Manual);

        jMenuBar1.add(jMenu_About);

        setJMenuBar(jMenuBar1);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened
        // TODO add your handling code here:
//        setSize(600, 600);
        filterFrame.setVisible(false);
    }//GEN-LAST:event_formWindowOpened

    private void jMenuItem_OpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem_OpenActionPerformed
        // TODO add your handling code here:
        String pathFile;

        JFileChooser fileChooser = new JFileChooser();
        int result = fileChooser.showOpenDialog(null);

        if (result == JFileChooser.APPROVE_OPTION) {
            File selectedFile = fileChooser.getSelectedFile();
            pathFile = selectedFile.getPath();

            this.setTitle("WISIM - " + selectedFile.getName());
            System.out.println(pathFile);

            onFileOpen(pathFile);
            System.out.println(pathFile);
        }

    }//GEN-LAST:event_jMenuItem_OpenActionPerformed

    private void jMenuItem_ExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem_ExitActionPerformed
        // TODO add your handling code here:
        formWindowClosing(null);
    }//GEN-LAST:event_jMenuItem_ExitActionPerformed

    private void jMenuItemOptionalSimulateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemOptionalSimulateActionPerformed
        // TODO add your handling code here:
        filterFrame.setVisible(true);
    }//GEN-LAST:event_jMenuItemOptionalSimulateActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        // TODO add your handling code here:
        filterFrame.dispose();
        try {
            wiEngine.stop();
        } catch (WiException ex) {
            System.out.println("can not stop engine");
        }
        drawer.Stop();
        dispose();
    }//GEN-LAST:event_formWindowClosing

    private void jMenuItemCopyToClBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemCopyToClBActionPerformed
        // TODO add your handling code here:
        filterFrame.addClipboardNodeIds(choseElements);
    }//GEN-LAST:event_jMenuItemCopyToClBActionPerformed

    private void jMenuItemFocusOnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemFocusOnActionPerformed
        // TODO add your handling code here:
        doneSelectedViewMenu();
        isFocused = true;
        ArrayList<Integer> tmpNodes = new ArrayList<>();
        for (String id : choseElements) {
            if (graph.getNode(id) != null) {
                tmpNodes.add(Integer.parseInt(id));
            }
        }

        DrawNodes(tmpNodes);
    }//GEN-LAST:event_jMenuItemFocusOnActionPerformed

    private void jMenuItemPropertyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemPropertyActionPerformed
        // TODO add your handling code here:
        if (selectedNodeId != null) {
            int nId = Integer.parseInt(selectedNodeId);
            Node node = wiEngine.getNode(nId);
            if (nodeProperty == null) {
                nodeProperty = new NodeProperties(node);
            } else {
                nodeProperty.setNode(node);
            }
            nodeProperty.setVisible(true);
            selectedNodeId = null;
        } else if (selectedPacketId != null) {
            Packet p = wiEngine.getPacket(Integer.parseInt(selectedPacketId));
            if (packetProperty == null) {
                packetProperty = new PacketProperties(this, p);
            }
            packetProperty.setPacket(p);
            packetProperty.setVisible(true);
            selectedPacketId = null;
        }
    }//GEN-LAST:event_jMenuItemPropertyActionPerformed

    private void jMenuItemResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemResetActionPerformed
        // TODO add your handling code here:
        drawNodes();
        isFocused = false;
    }//GEN-LAST:event_jMenuItemResetActionPerformed

    private void jCheckBoxMenuNodeLabelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxMenuNodeLabelActionPerformed
        // TODO add your handling code here:
        boolean b = jCheckBoxMenuNodeLabel.getState();
        if (!wiEngine.isStop()) {
            jCheckBoxMenuNodeLabel.setState(!b);
            return;
        }

        setNodeLabel(b);
    }//GEN-LAST:event_jCheckBoxMenuNodeLabelActionPerformed

    private void jPopupMenu1PopupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {//GEN-FIRST:event_jPopupMenu1PopupMenuWillBecomeInvisible
        // TODO add your handling code here:\
        //view.beginSelectionAt(0, 0);
        //view.endSelectionAt(0, 0);
        //view.invalidate();
    }//GEN-LAST:event_jPopupMenu1PopupMenuWillBecomeInvisible
    private void doneSelectedViewMenu() {
        System.out.println("doneSelectedViewmenu");
        view.beginSelectionAt(0, 0);
        view.endSelectionAt(0, 0);

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            //UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
        }
        //</editor-fold>

        System.err.println(wiBase.WiException.TYPE_CHANGEABLE);
        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                GraphForm graphForm = new GraphForm();
                graphForm.setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JRadioButtonMenuItem j1RadioButtonMenuItem;
    private javax.swing.JRadioButtonMenuItem j1_100RadioButtonMenuItem;
    private javax.swing.JCheckBoxMenuItem jCheckBoxMenuNodeLabel;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu2;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JMenuItem jMenuItemCopyToClB;
    private javax.swing.JMenuItem jMenuItemFocusOn;
    private javax.swing.JMenuItem jMenuItemOptionalSimulate;
    private javax.swing.JMenuItem jMenuItemProperty;
    private javax.swing.JMenuItem jMenuItemReset;
    private javax.swing.JMenuItem jMenuItem_Author;
    private javax.swing.JMenuItem jMenuItem_Exit;
    private javax.swing.JMenuItem jMenuItem_Export;
    private javax.swing.JMenuItem jMenuItem_Manual;
    private javax.swing.JMenuItem jMenuItem_Open;
    private javax.swing.JMenu jMenu_About;
    private javax.swing.JMenu jMenu_File;
    private javax.swing.JMenu jMenu_Tool;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPopupMenu jPopupMenu1;
    private javax.swing.JRadioButtonMenuItem jRadioButtonMenuItem110;
    private javax.swing.JRadioButtonMenuItem jRadioButtonMenuItem120;
    private javax.swing.JRadioButtonMenuItem jRadioButtonMenuItem150;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JSplitPane jSplitPane2;
    private javax.swing.ButtonGroup speedButtonGroup;
    private javax.swing.JTextPane tp_console;
    // End of variables declaration//GEN-END:variables
// <editor-fold defaultstate="collapsed" desc="IControlContainer">

    @Override
    public void onNodeClick(String nodes) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void onSpriteClick(String nodes) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    String getPacketId(String spriteId) {
        return spriteId.split("-")[0];
    }

    @Override
    public void onSpriteSelected(String id) {
        if (id != null && !id.equals("")) {
            selectedPacketId = getPacketId(id);
            Point p = java.awt.MouseInfo.getPointerInfo().getLocation();
            resetPopupMenu();
            jMenuItemProperty.setEnabled(true);
            jPopupMenu1.show(this, p.x - getLocation().x, p.y - getLocation().y);
        }
    }

    void resetPopupMenu() {
        for (Object item : jPopupMenu1.getComponents()) {
            if (item instanceof JMenuItem) {
                JMenuItem menuItem = (JMenuItem) item;
                menuItem.setEnabled(false);
            }
        }
    }

    @Override
    public void onRightClick(ArrayList<String> nodes) {
        Point p = java.awt.MouseInfo.getPointerInfo().getLocation();
        choseElements.clear();
        choseElements.addAll(nodes);
        if (!wiEngine.isPlay()) {
            if (nodes.size() == 0) {
                // isPause
                if (!wiEngine.isStop() || !wiEngine.isParsed() || !isFocused) {
                    return;
                }

                // isStop
                resetPopupMenu();
                jMenuItemReset.setEnabled(true);
                jPopupMenu1.show(this, p.x - getLocation().x, p.y - getLocation().y);
            } else if (nodes.size() == 1) {
                selectedNodeId = nodes.get(0);
                resetPopupMenu();
                jMenuItemProperty.setEnabled(true);
                jMenuItemCopyToClB.setEnabled(true);
                jPopupMenu1.show(this, p.x - getLocation().x, p.y - getLocation().y);
            } else {
                resetPopupMenu();
                if(!isFocused){
                jMenuItemCopyToClB.setEnabled(true);
                jMenuItemFocusOn.setEnabled(true);
                jMenuItemProperty.setEnabled(true);
                jPopupMenu1.show(this, p.x - getLocation().x, p.y - getLocation().y);
                }
            }
        }
    }
    // </editor-fold>
// <editor-fold defaultstate="collapsed" desc="IEngineListener">

    @Override
    public void onNotification(Object... text) {
        return;
    }

    @Override
    public void onTraceFileChange(String traceFile) {
        return;
    }

    @Override
    public void onRun(long startTimeSecond, long endTimeSecond) {
        return;
    }

    @Override
    public void onPause() {
        return;
    }

    @Override
    public void onResume() {
        return;
    }

    @Override
    public void onStop() {
        return;
    }

    @Override
    public void onSpeedChange(double speed, TimeUnit timeunit) {
        return;
    }

    @Override
    public void onBeforeParse() {
        controlPane.setEnabled(false);
        return;
    }

    @Override
    public void onAfterParse(long timeParse) {
        System.out.println("Done Parsing..");
        controlPane.setEnabled(true);

        drawNodes();
        controlPane.setTotalTime(
                (long) wiEngine.getAdapter().getDurationSimulation() * (long) 1E3);
    }

    @Override
    public void onRunTimeChange(long startTimeSecond, long finishTimeSecond) {
        return;
    }

    @Override
    public void onUpdateCurrentTime(long startTime, long endTime, long currentTime) {
        if (controlPane != null) {
            controlPane.setCurrTime(currentTime / (long) 1E6);
        }
    }
    // </editor-fold>

    public void onNodePropertyRequest(String id) {
        Node n = wiEngine.getNode(Integer.parseInt(id));
        if (n != null) {
            if (nodeProperty == null) {
                nodeProperty = new NodeProperties(n);
            } else {
                nodeProperty.setNode(n);
            }

            nodeProperty.setVisible(true);
        }
    }

    public ArrayList<String> getCopiedPacketIDs() {
        return copiedPacketIDs;
    }
    ArrayList<String> copiedPacketIDs = new ArrayList<>();

    public void onPacketIdCopied(String packetId) {
        if (!copiedPacketIDs.contains(packetId)) {
            copiedPacketIDs.add(packetId);
        }
    }

    private void setNodeLabel(boolean b) {
        if (b) {
            for (org.graphstream.graph.Node node : graph.getNodeSet()) {
                node.setAttribute("ui.label", node.getId());
            }
        } else {
            for (org.graphstream.graph.Node node : graph.getNodeSet()) {
                node.setAttribute("ui.label", "");
            }
        }
    }
}
